package com.example.a2032.Utils;

import android.text.TextUtils;
import android.util.Log;

import com.example.a2032.db.DataDbHelper;
import com.example.a2032.db.dao.PPGDataDao;
import com.example.a2032.db.dao.RealTimeStepDao;
import com.example.a2032.db.dao.SleepDataDao;
import com.example.a2032.entity.EcgSaveInfo;
import com.example.a2032.entity.PPGMeasureData;
import com.example.a2032.entity.RealTimeData;
import com.example.a2032.entity.SleepData;
import com.example.a2032.net.jstylenet.JstyleConst;
import com.example.a2032.net.jstylenet.NetSendUtils;
import com.example.a2032.net.jstylenet.UploadData;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.ArrayList;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Function;

public class HistoryDataUploadUtils {
    private static final String TAG = "HistoryDataUploadUtils";

    public static void uploadData() {
        PPGDataDao ppgDataDao = DataDbHelper.getInstance().getPPGDataDao();
        Log.i(TAG, "uploadData: " + WebSocketUtils.getInstance().isConnected());
        if (!WebSocketUtils.getInstance().isConnected()) return;
        upLoadEcgData();
        upLoadSleepHistoryData();
        upLoadStepHistoryData();
        String lastUploadDate = SharedPreferenceUtils.getSpString(SharedPreferenceUtils.KEY_LastUploadHistoryDate);
        if (TextUtils.isEmpty(lastUploadDate)) lastUploadDate = "2000.01.01 00:00:00";
        List<PPGMeasureData> ppgMeasureDataList = ppgDataDao.getLastPPGData(lastUploadDate);
        if (ppgMeasureDataList.size() == 0) return;
//        List<PPGMeasureData> hrList = ppgDataDao.getLastPPGData(lastUploadDate, PPGMeasureData.MeasureData_PPGHR);
//        List<PPGMeasureData> bpList = ppgDataDao.getLastPPGData(lastUploadDate, PPGMeasureData.MeasureData_PPGBP);
//        List<PPGMeasureData> spo2List = ppgDataDao.getLastPPGData(lastUploadDate, PPGMeasureData.MeasureData_PPGSPO2);
        List<PPGMeasureData> hrList = new ArrayList<>();
        List<PPGMeasureData> bpList = new ArrayList<>();
        List<PPGMeasureData> spo2List = new ArrayList<>();
        for (PPGMeasureData ppgMeasureData : ppgMeasureDataList) {
            int type = ppgMeasureData.getDataType();
            Log.i(TAG, "uploadData: " + ppgMeasureData.getDate());
            if (type == PPGMeasureData.MeasureData_PPGHR) {
                hrList.add(ppgMeasureData);
            } else if (type == PPGMeasureData.MeasureData_PPGBP) {
                bpList.add(ppgMeasureData);
            } else if (type == PPGMeasureData.MeasureData_PPGSPO2) {
                spo2List.add(ppgMeasureData);
            }
        }
        lastUploadDate = ppgMeasureDataList.get(0).getDate();
        Log.i(TAG, "uploadData: " + lastUploadDate);

        WebSocketUtils.getInstance().sendMsg(NetSendUtils.uploadHeartData(hrList));
        WebSocketUtils.getInstance().sendMsg(NetSendUtils.upBPData(bpList));
        WebSocketUtils.getInstance().sendMsg(NetSendUtils.upSpo2Data(spo2List));
        //需增加网络判断，上传成功后才能更新时间
        SharedPreferenceUtils.setSpString(SharedPreferenceUtils.KEY_LastUploadHistoryDate, lastUploadDate);
    }

    public static void upLoadSleepHistoryData() {
        String lastUploadDate = SharedPreferenceUtils.getSpString(SharedPreferenceUtils.KEY_LastUploadSleepDate);
        Log.i(TAG, "upLoadSleepHistoryData: "+lastUploadDate);
        if (TextUtils.isEmpty(lastUploadDate)) lastUploadDate = "2000.01.01 00:00:00";
        lastUploadDate = DateUtils.getLastUploadDate(lastUploadDate);
        SleepDataDao sleepDataDao = DataDbHelper.getInstance().getSleepDataDao();
        List<SleepData> ppgMeasureDataList = sleepDataDao.getLastPPGData(lastUploadDate);
        if (ppgMeasureDataList.size() == 0) return;
        String lastDate = ppgMeasureDataList.get(0).getDate();
        Observable.fromIterable(ppgMeasureDataList).buffer(30).subscribe(new Observer<List<SleepData>>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(List<SleepData> list) {
                WebSocketUtils.getInstance().sendMsg(NetSendUtils.upLoadSleepData(ppgMeasureDataList));
            }

            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
            }

            @Override
            public void onComplete() {
                Log.i(TAG, "onComplete: " + lastDate);
                SharedPreferenceUtils.setSpString(SharedPreferenceUtils.KEY_LastUploadSleepDate, lastDate);
            }
        });

    }
    public static void upLoadStepHistoryData() {
        String lastUploadDate = SharedPreferenceUtils.getSpString(SharedPreferenceUtils.KEY_LastUploadStepDate);
        if (TextUtils.isEmpty(lastUploadDate)) lastUploadDate = "2000.01.01";
        //lastUploadDate = DateUtils.getLastUploadDate(lastUploadDate);
        RealTimeStepDao realTimeStepDao = DataDbHelper.getInstance().getRealTimeStepDao();
        List<RealTimeData> ppgMeasureDataList = realTimeStepDao.getLastPPGData(lastUploadDate);
        if (ppgMeasureDataList.size() == 0) return;
        String lastDate = ppgMeasureDataList.get(0).getDate();
        Observable.fromIterable(ppgMeasureDataList).buffer(30).subscribe(new Observer<List<RealTimeData>>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(List<RealTimeData> list) {
                WebSocketUtils.getInstance().sendMsg(NetSendUtils.upLoadStepData(ppgMeasureDataList));
            }

            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
            }

            @Override
            public void onComplete() {
                Log.i(TAG, "onComplete: " + lastDate);
                SharedPreferenceUtils.setSpString(SharedPreferenceUtils.KEY_LastUploadStepDate, lastDate);
            }
        });

    }

    public static void upLoadEcgData() {
        String lastUploadDate = SharedPreferenceUtils.getSpString(SharedPreferenceUtils.KEY_LastUploadEcgDate);
        if (TextUtils.isEmpty(lastUploadDate)) lastUploadDate = "2000.01.01 00:00:00";
        List<EcgSaveInfo> ecgSaveInfos = DataDbHelper.getInstance().getEcgInfoDao().getLastEcgData(lastUploadDate);
        if (ecgSaveInfos.size() == 0) return;
        Observable.fromIterable(ecgSaveInfos).map(new Function<EcgSaveInfo, UploadData.DataTotalEcg>() {
            @Override
            public UploadData.DataTotalEcg apply(EcgSaveInfo ecgSaveInfo) throws Exception {
                return getEcgData(ecgSaveInfo);
            }
        }).compose(SchedulersTransformer.io2MainObservable()).subscribe(new Observer<UploadData.DataTotalEcg>() {
            @Override
            public void onSubscribe(Disposable d) {


            }

            @Override
            public void onNext(UploadData.DataTotalEcg dataTotalEcg) {
                if (dataTotalEcg.getEcgs().size() != 0) {
                    List data = new ArrayList();
                    data.add(dataTotalEcg);

                    //ecg数据量太大，一次只能传一条
                    WebSocketUtils.getInstance().sendMsg(NetSendUtils.uploadHistoryData(JstyleConst.DataTYPE_ECG, data));


                }
            }

            @Override
            public void onError(Throwable e) {
                Log.i(TAG, "onError: " + e.getMessage());
            }

            @Override
            public void onComplete() {
                SharedPreferenceUtils.setSpString(SharedPreferenceUtils.KEY_LastUploadEcgDate, ecgSaveInfos.get(0).getDate());
            }
        });

    }

    public static UploadData.DataTotalEcg getEcgData(EcgSaveInfo ecgSaveInfo) {
        String rootPath = ecgSaveInfo.getRootPath();
        String date = ecgSaveInfo.getDate();
        File file = new File(rootPath, date + ".ecg");
        List<Integer> list = new ArrayList<>();
        if (file.exists()) {
            list = readFile(file.getAbsolutePath());
        }
        return getEcgData(ecgSaveInfo, list);
    }

    public static UploadData.DataTotalEcg getEcgData(EcgSaveInfo ecgSaveInfo, List data) {
        String date = ecgSaveInfo.getDate();
        UploadData.DataTotalEcg dataTotalBean = new UploadData.DataTotalEcg();
        dataTotalBean.setEcgs(data);
        dataTotalBean.setTime(date);
        dataTotalBean.setMaxhr(ecgSaveInfo.getMaxHeartRate());
        dataTotalBean.setMinhr(ecgSaveInfo.getMinHeartRate());
        dataTotalBean.setAvghr(ecgSaveInfo.getHeartRate());
        dataTotalBean.setHrv(ecgSaveInfo.getHrv());
        return dataTotalBean;
    }

    private static List<Integer> readFile(String path) {

        long start = System.currentTimeMillis();
        FileChannel fc = null;
        List<Integer> data = new ArrayList<>();
        StringBuffer stringBuffer = new StringBuffer();
        try {
            fc = new FileInputStream(path).getChannel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            Charset charset = Charset.forName("UTF-8");
            CharsetDecoder charsetDecoder = charset.newDecoder();

            try {
                while (fc.read(buffer) != -1) {
                    buffer.flip();
                    stringBuffer.append(charsetDecoder.decode(buffer));
                    buffer.clear();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        String[] dataString = stringBuffer.toString().split(",");
        for (String value : dataString) {//纯数字写进null字符串?
            // Log.i(TAG, "readFile2: "+value);
            if (TextUtils.isEmpty(value) || "null".equals(value) || "-".equals(value)) continue;
            if (value.contains("-")) {
                if (value.lastIndexOf("-") == 0) data.add(Integer.valueOf(value));
            } else {
                int doubleValue = Integer.valueOf(value);
                if (doubleValue > 8000) doubleValue = 8000;
                if (doubleValue < -8000) doubleValue = -8000;
                data.add(doubleValue);
            }

        }
        long end = System.currentTimeMillis();
        Log.i(TAG, "readFile2: " + (end - start));
        return data;
    }

}
